<!DOCTYPE html>
<html>

<head> 
    <meta charset="utf-8"> 
    <title>经伟度坐标转成平面地图上的点</title> 
</head>
<style>
    body{
    padding: 0;
    margin: 0;
    font-size: 0;
  }
    div{
    position: relative;
  }
  p{
    font-size: 14px;
    position: fixed;
    left: 10px;
    top: 0;
  }
  img{
    min-width: 100%;
    /*height: auto;*/
  }
   span{
    position: absolute;
    display: inline-block;
    background: #f00;
    transform: translate(-50%,-50%);
    width: 1px;
    height: 1px;
    border-radius: 50%;
       animation: myfirst 2s linear 3s infinite normal;
   }
   input{
    padding: 5px 10px;
    width: 300px;
   }
   input[type=button]{
    width: 100px;
   }
   @keyframes myfirst
   {
       0% {width: 100px;height: 100px;opacity: 0}
       80%   {width: 1px;height: 1px;opacity: 1;}
       100%   {width: 1px;height: 1px;opacity: 1;}
   }

</style>

<body onload="init()">
    <div><img src="maps.jpg"><span id="gz"></span></div>
    <p>
        经纬度: <input type="Nunber" id="lng_lat" value="113.26436,23.12908">
        <input type="button" id="b1" onclick="displayResult()" value="设置位置">
    </p>
</body>
<script type="text/javascript">
//获取元素
let gz = document.querySelector("#gz")
let lng_lat = document.querySelector("#lng_lat")
let img = document.querySelector('img')

// 平面坐标转换经纬度
let webMercator2LngLat = (x, y) => {
    let lng = (x / 20037508.34) * 180;
    let lat = (y / 20037508.34) * 180;
    lat =
        (180 / Math.PI) *
        (2 * Math.atan(Math.exp((lat * Math.PI) / 180)) - Math.PI / 2);
    return [lng, lat];
};
// 经纬度转墨卡托平面坐标
/*
lng 经度,
lat 纬度,
*/
let lngLat2WebMercator = (lng, lat) => {
    let earthRad = 6378137.0;
    let x = ((lng * Math.PI) / 180) * earthRad;
    let a = (lat * Math.PI) / 180;
    let y =
        (earthRad / 2) * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
    return [x, y];
};

/*
 xy:[
 [左上角经度,左上角纬度],
 [右下角经度,右下角纬度]
 ]
 */
let xy = [
        [-180, 85.05112877980659],
        [180, -85.05112877980659],
    ],
    // 图片宽高 比例
    img_w = 0,
    img_h = 0,
    w_ratio = 0,
    h_ratio = 0

let a = lngLat2WebMercator(xy[0][0], xy[0][1])
let b = lngLat2WebMercator(xy[1][0], xy[1][1])

// 初始化
function init() {
    // 获取元素没有通过css 设置的样式
    let cs = window.getComputedStyle(img);
    img_h = cs.getPropertyValue('height').split('px')[0]
    img_w = cs.getPropertyValue('width').split('px')[0]

    // 计算当前img与地球的比例
    w_ratio = (b[0] - a[0]) / img_w
    h_ratio = (a[1] - b[1]) / img_h

    console.log('w_ratio:', w_ratio)
    console.log('h_ratio:', h_ratio)

    displayResult()
}


/*
广州市
latitude: "23.12908"
longitude: "113.26436"
*/

/*
北京
116.40
39.90
*/

/*
Harbin 哈尔滨市
经度：126.53
纬度：45.80
*/
/*
江西
114.922891349
25.386911698
*/

let displayResult = (lng = lng_lat.value.replace(/\，/g, ',').split(',')[0], lat = lng_lat.value.replace(/\，/g, ',').split(',')[1]) => {

    let seat = lngLat2WebMercator(lng, lat)
    console.log(seat)
    let x = (seat[0] - a[0]) / w_ratio
    let y = (a[1] - seat[1]) / h_ratio
    setLocation(x, y)
}
// 设置小红点位置
let setLocation = (nl, nt) => {
    gz.style.left = nl + 'px';
    gz.style.top = nt + 'px';

    let [lng, lat] = webMercator2LngLat(nl * w_ratio + a[0], a[1] - nt * h_ratio)
    lng_lat.value = lng + ',' + lat
    if (isDown == false) {
        gz.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' })
    }

}

// 页面窗口大小改变
window.onresize = function() {
    init();
}
// 点击设置位置
img.onclick = function(e) {
    //获取x坐标和y坐标 包括滚动卷入
    let nx = e.offsetX;
    let ny = e.offsetY;
    setLocation(nx, ny)
}

// 下面是鼠标移动
var x = 0;
var y = 0;
var l = 0;
var t = 0;
var isDown = false;
//鼠标按下事件
gz.onmousedown = function(e) {
    //获取x坐标和y坐标
    x = e.clientX;
    y = e.clientY;

    //获取左部和顶部的偏移量
    l = gz.offsetLeft;
    t = gz.offsetTop;
    //开关打开
    isDown = true;
    //设置样式  
    gz.style.cursor = 'move';
}
//鼠标移动
window.onmousemove = function(e) {
    if (isDown == false) {
        return;
    }
    //获取x和y
    let nx = e.clientX;
    let ny = e.clientY;
    //计算移动后的左偏移量和顶部的偏移量
    let nl = nx - (x - l);
    let nt = ny - (y - t);

    setLocation(nl, nt)

}
//鼠标抬起事件
gz.onmouseup = function() {
    //开关关闭
    isDown = false;
    gz.style.cursor = 'default';
}

// --------------------------------------------
</script>